﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.ClayObject;
using SHZY.Common.Configuration;
using SHZY.Common.Models.NPOI;
using SHZY.DataEncryption;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Models;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.Permission;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SHZY.BaseData.Entitys.Dto.QmsBaseMastercheckdist;
using SHZY.BaseData.Entitys;
using SHZY.BaseData.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SHZY.Extend.Entitys;
using SHZY.Extend.Entitys.Dto.Employee;
using SHZY.BaseData.Entitys.Entity;

namespace SHZY.BaseData;

/// <summary>
/// 业务实现：检验任务分配.
/// </summary>
[ApiDescriptionSettings(Tag = "BaseData", Name = "Mastercheckdist", Order = 200)]
[Route("api/BaseData/[controller]")]
public class QmsBaseMastercheckdistService : IQmsBaseMastercheckdistService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.​
    /// </summary>
    private readonly ISqlSugarRepository<QmsBaseMastercheckdistEntity> _repository;

    /// <summary>
    /// 多租户事务.
    /// </summary>
    private readonly ITenant _db;

    /// <summary>
    /// 数据接口服务.
    /// </summary>
    private readonly IDataInterfaceService _dataInterfaceService;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;

    /// <summary>
    /// 初始化一个<see cref="QmsBaseMastercheckdistService"/>类型的新实例.
    /// </summary>
    public QmsBaseMastercheckdistService(
        ISqlSugarRepository<QmsBaseMastercheckdistEntity> qmsBaseMastercheckdistRepository,
        IDataInterfaceService dataInterfaceService,
        ISqlSugarClient context,
        IUserManager userManager)
    {
        _repository = qmsBaseMastercheckdistRepository;
        _dataInterfaceService = dataInterfaceService;
        _db = context.AsTenant();
        _userManager = userManager;
    }

    /// <summary>
    /// 获取检验任务分配.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        var res = await _repository.Context.Queryable<QmsBaseMastercheckdistEntity>()
            .LeftJoin<BaseuserEntity>((a, b) => a.EmployeeCode == b.Account)
            .LeftJoin<QmsBaseMaterialEntity>((a, b, c) => a.MatnrCode == c.Code)
            .LeftJoin<QmsBaseMaterialgroupEntity>((a, b, c, d) => a.MatnrGroupCode == d.Code)
            .LeftJoin<QmsBaseSupplierEntity>((a, b, c, d, e) => a.SupplierNo == e.Code)
            .Where(a => a.DeleteMark == null)
            .Where(a => a.Id == id)
            .Select((a, b, c, d, e) => new QmsBaseMastercheckdistInfoOutput
            {
                id = a.Id,
                matnrCode = a.MatnrCode,
                matnrGroupCode = a.MatnrGroupCode,
                supplierNo = a.SupplierNo,
                supplierClassify = a.SupplierClassify,
                employeeCode = a.EmployeeCode,
                creatorUserId = a.CreatorUserId,
                creatorTime = a.CreatorTime,
                lastModifyUserId = a.LastModifyUserId,
                lastModifyTime = a.LastModifyTime,
                enabledMark = a.EnabledMark,
                enabledMarkDesc = SqlFunc.IIF(a.EnabledMark == 0, "无效", "有效"),
                empEnCode = b.Account,
                empFullName = b.RealName,
                //empDepartmentName = b.DepartmentName,
                materialCode = c.Code,
                materialName = c.Name,
                materialType = c.Type,
                materialGroup = c.MaterialGroupCode,
                materialGroupName = d.Name,
                materialGroupCode = d.Code,
                supplierName = e.Name,
                supplierCode = e.Code,
            }).FirstAsync();
        //.Adapt<QmsBaseMastercheckdistInfoOutput>();

        return res;
    }

    /// <summary>
    /// 获取检验员列表.
    /// </summary>
    /// <returns></returns>
    [HttpGet("Inspectors")]
    public async Task<dynamic> GetInspectors()
    {
        var result = await _repository.Context.Queryable<BaseuserEntity>()
            .Where(w => w.DeleteMark == null)
            .Where(w => w.EnabledMark == 1)
            .OrderBy(w => w.RealName)
            .Select(w => new
            {
                id = w.Id,
                enCode = w.Account,
                fullName = w.RealName,
                departmentName = "",
            }).ToListAsync();

        return result;
    }

    /// <summary>
    /// 获取检验任务分配列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] QmsBaseMastercheckdistListQueryInput input)
    {
        var query = _repository.Context.Queryable<QmsBaseMastercheckdistEntity>()
            .LeftJoin<BaseuserEntity>((a, b) => a.EmployeeCode == b.Account)
            .LeftJoin<QmsBaseMaterialEntity>((a, b, c) => a.MatnrCode == c.Code)
            .LeftJoin<QmsBaseMaterialgroupEntity>((a, b, c, d) => a.MatnrGroupCode == d.Code)
            .LeftJoin<QmsBaseSupplierEntity>((a, b, c, d, e) => a.SupplierNo == e.Code)
            .LeftJoin<DictionaryDataEntity>((a, b, c, d, e, f) => a.SupplierClassify == f.EnCode)
            .Where((a, b, c, d, e,f) => a.DeleteMark == null && b.DeleteMark == null && c.DeleteMark == null && d.DeleteMark == null && e.DeleteMark == null&&f.DeleteMark==null)
            .WhereIF(!string.IsNullOrEmpty(input.matnrCode), a => a.MatnrCode.Equals(input.matnrCode))
            .WhereIF(!string.IsNullOrEmpty(input.matnrGroupCode), a => a.MatnrGroupCode.Equals(input.matnrGroupCode))
            .WhereIF(!string.IsNullOrEmpty(input.supplierNo), a => a.SupplierNo.Equals(input.supplierNo))
            .WhereIF(!string.IsNullOrEmpty(input.supplierClassify), a => a.SupplierClassify.Equals(input.supplierClassify))
            .WhereIF(!string.IsNullOrEmpty(input.employeeCode), (a, b, c, d, e) => a.EmployeeCode.Equals(input.employeeCode))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.MatnrCode.Contains(input.keyword) || a.MatnrGroupCode.Contains(input.keyword) || a.SupplierNo.Contains(input.keyword) || a.SupplierClassify.Contains(input.keyword) || a.EmployeeCode.Contains(input.keyword))
            //.OrderByIF(string.IsNullOrEmpty(input.sidx), a => a.Id)
            //.OrderByIF(!string.IsNullOrEmpty(input.sidx), a => input.sidx + " " + input.sort)
            .Select((a, b, c, d, e,f) => new QmsBaseMastercheckdistInfoOutput
            {
                id = a.Id,
                matnrCode = a.MatnrCode,
                matnrGroupCode = a.MatnrGroupCode,
                supplierNo = a.SupplierNo,
                supplierClassify =a.SupplierClassify,
                employeeCode = a.EmployeeCode,
                creatorUserId = a.CreatorUserId,
                creatorTime = a.CreatorTime,
                lastModifyUserId = a.LastModifyUserId,
                lastModifyTime = a.LastModifyTime,
                enabledMark = a.EnabledMark,
                enabledMarkDesc = SqlFunc.IIF(a.EnabledMark == 0, "无效", "有效"),
                empEnCode = b.Account,
                empFullName = b.RealName,
                //empDepartmentName = b.DepartmentName,
                materialCode = c.Code,
                materialName = c.Name,
                materialType = c.Type,
                materialGroup = c.MaterialGroupCode,
                materialGroupName = d.Name,
                materialGroupCode = d.Code,
                supplierName = e.Name,
                supplierCode = e.Code,
                supplierClassifyName= f.FullName

            }).MergeTable();
        if (!string.IsNullOrEmpty(input.sidx))
        {
            query.OrderBy(input.sidx + " " + input.sort);
        }
        else
        {
            query.OrderBy(it => it.id);
        }
        string sql = query.ToSql().Key;
        var data = await query.ToPagedListAsync(input.currentPage, input.pageSize);
        var result = PageResult<QmsBaseMastercheckdistInfoOutput>.SqlSugarPageResult(data);

        return result;
    }

    /// <summary>
    /// 新建检验任务分配.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] QmsBaseMastercheckdistCrInput input)
    {
        if (await _repository
            .Where(w => w.EmployeeCode == input.employeeCode)
            .Where(w => w.SupplierNo == input.supplierNo)
            .Where(w => w.SupplierClassify == input.supplierClassify)
            .Where(w => w.MatnrCode == input.matnrCode)
            .Where(w => w.MatnrGroupCode == input.matnrGroupCode)
            .AnyAsync(x => x.DeleteMark == null))
            throw Oops.Oh(ErrorCode.COM1004);

        var entity = input.Adapt<QmsBaseMastercheckdistEntity>();
        entity.Id = SnowflakeIdHelper.NextId();
        entity.CreatorUserId = _userManager.UserId;
        entity.CreatorTime = DateTime.Now;
        var isOk = await _repository.Context
            .Insertable(entity)
            .IgnoreColumns(ignoreNullColumn: true)
            .CallEntityMethod(m => m.Creator())
            .ExecuteCommandAsync();
        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
    }

    /// <summary>
    /// 获取检验任务分配无分页列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    private async Task<dynamic> GetNoPagingList([FromQuery] QmsBaseMastercheckdistListQueryInput input)
    {

        var query = _repository.Context.Queryable<QmsBaseMastercheckdistEntity>()
            .LeftJoin<EmployeeEntity>((a, b) => a.EmployeeCode == b.EnCode)
            .LeftJoin<QmsBaseMaterialEntity>((a, b, c) => a.MatnrCode == c.Code)
            .LeftJoin<QmsBaseMaterialgroupEntity>((a, b, c, d) => a.MatnrGroupCode == d.Code)
            .LeftJoin<QmsBaseSupplierEntity>((a, b, c, d, e) => a.SupplierNo == e.Code)
            .LeftJoin<DictionaryDataEntity>((a, b, c, d, e, f) => a.SupplierClassify == f.EnCode)
            .Where((a, b, c, d, e, f) => a.DeleteMark == null && b.DeleteMark == null && c.DeleteMark == null && d.DeleteMark == null && e.DeleteMark == null && f.DeleteMark == null)
            .WhereIF(!string.IsNullOrEmpty(input.matnrCode), a => a.MatnrCode.Equals(input.matnrCode))
            .WhereIF(!string.IsNullOrEmpty(input.matnrGroupCode), a => a.MatnrGroupCode.Equals(input.matnrGroupCode))
            .WhereIF(!string.IsNullOrEmpty(input.supplierNo), a => a.SupplierNo.Equals(input.supplierNo))
            .WhereIF(!string.IsNullOrEmpty(input.supplierClassify), a => a.SupplierClassify.Equals(input.supplierClassify))
            .WhereIF(!string.IsNullOrEmpty(input.employeeCode), a => a.EmployeeCode.Equals(input.employeeCode))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.MatnrCode.Contains(input.keyword) || a.MatnrGroupCode.Contains(input.keyword) || a.SupplierNo.Contains(input.keyword) || a.SupplierClassify.Contains(input.keyword) || a.EmployeeCode.Contains(input.keyword))
            .OrderByIF(string.IsNullOrEmpty(input.sidx), a => a.Id)
            .OrderByIF(!string.IsNullOrEmpty(input.sidx), a => input.sidx + " " + input.sort)
            .Select((a, b, c, d, e, f) => new QmsBaseMastercheckdistInfoOutput
            {
                id = a.Id,
                matnrCode = a.MatnrCode,
                matnrGroupCode = a.MatnrGroupCode,
                supplierNo = a.SupplierNo,
                supplierClassify = a.SupplierClassify,
                employeeCode = a.EmployeeCode,
                creatorUserId = a.CreatorUserId,
                creatorTime = a.CreatorTime,
                lastModifyUserId = a.LastModifyUserId,
                lastModifyTime = a.LastModifyTime,
                enabledMark = a.EnabledMark,
                enabledMarkDesc = a.EnabledMark.ToString(),//SqlFunc.IIF(a.EnabledMark == 0, "无效", "有效"),
                empEnCode = b.EnCode,
                empFullName = b.FullName,
                empDepartmentName = b.DepartmentName,
                materialCode = c.Code,
                materialName = c.Name,
                materialType = c.Type,
                materialGroup = c.MaterialGroupCode,
                materialGroupName = d.Name,
                materialGroupCode = d.Code,
                supplierName = e.Name,
                supplierCode = e.Code,
                supplierClassifyName=f.FullName
            });
        //return await _repository.Context.Queryable<QmsBaseMastercheckdistEntity, UserEntity, UserEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.CreatorUserId == b.Id, JoinType.Left, a.LastModifyUserId == c.Id))
        //    .Where(a => a.DeleteMark == null)
        //    .WhereIF(!string.IsNullOrEmpty(input.matnrCode), a => a.MatnrCode.Contains(input.matnrCode))
        //    .WhereIF(!string.IsNullOrEmpty(input.matnrGroupCode), a => a.MatnrGroupCode.Contains(input.matnrGroupCode))
        //    .WhereIF(!string.IsNullOrEmpty(input.supplierNo), a => a.SupplierNo.Contains(input.supplierNo))
        //    .WhereIF(!string.IsNullOrEmpty(input.supplierClassify), a => a.SupplierClassify.Contains(input.supplierClassify))
        //    .WhereIF(!string.IsNullOrEmpty(input.employeeCode), a => a.EmployeeCode.Contains(input.employeeCode))
        //    .WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.MatnrCode.Contains(input.keyword) || a.MatnrGroupCode.Contains(input.keyword) || a.SupplierNo.Contains(input.keyword) || a.SupplierClassify.Contains(input.keyword) || a.EmployeeCode.Contains(input.keyword))
        //    .OrderByIF(string.IsNullOrEmpty(input.sidx), a => a.Id)
        //    .Select((a, b, c) => new QmsBaseMastercheckdistListOutput
        //    {
        //        id = a.Id,
        //        matnrCode = a.MatnrCode,
        //        matnrGroupCode = a.MatnrGroupCode,
        //        supplierNo = a.SupplierNo,
        //        supplierClassify = a.SupplierClassify,
        //        employeeCode = a.EmployeeCode,
        //        enabledMark = SqlFunc.IIF(a.EnabledMark == 0, "无效", "有效"),
        //    }).OrderByIF(!string.IsNullOrEmpty(input.sidx), a => input.sidx + " " + input.sort).ToListAsync();

        return await query.ToListAsync();
    }

    /// <summary>
    /// 导出检验任务分配.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("Actions/Export")]
    public async Task<dynamic> Export([FromQuery] QmsBaseMastercheckdistListQueryInput input)
    {
        var exportData = new List<QmsBaseMastercheckdistInfoOutput>();
        if (input.dataType == 0)
        {
            var data = await GetList(input);
            exportData = Clay.Object(data).Solidify<PageResult<QmsBaseMastercheckdistInfoOutput>>().list;
        }
        else
            exportData = await GetNoPagingList(input);
        //List<ParamsModel> paramList = "[{\"value\":\"物料编码\",\"field\":\"matnrCode\"},{\"value\":\"物料组编码\",\"field\":\"matnrGroupCode\"},{\"value\":\"供应商编码\",\"field\":\"supplierNo\"},{\"value\":\"供应商分类\",\"field\":\"supplierClassify\"},{\"value\":\"员工号\",\"field\":\"employeeCode\"},{\"value\":\"有效标志\",\"field\":\"enabledMark\"},]".ToList<ParamsModel>();
        List<ParamsModel> paramList = new List<ParamsModel>
        {
            new ParamsModel{ value="物料名称", field="materialName" },
            new ParamsModel{ value="物料编码", field="matnrCode" },
            new ParamsModel{ value="物料组编码", field="matnrGroupCode" },
            new ParamsModel{ value="物料组名称", field="materialGroupName" },
            new ParamsModel{ value="供应商", field="supplierName" },
            new ParamsModel{ value="供应商编码", field="supplierNo" },
            new ParamsModel{ value="供应商分类", field="supplierClassifyName" },
            new ParamsModel{ value="检验员", field="empFullName" },
            new ParamsModel{ value="检验员编号", field="employeeCode" },
            new ParamsModel{ value="员工部门", field="empDepartmentName" },
            new ParamsModel{ value="供应商编号", field="supplierCode" },
            //new ParamsModel{ value="物料类型", field="materialType" },
            new ParamsModel{ value="有效标志", field="enabledMarkDesc" },
        };
        ExcelConfig excelconfig = new ExcelConfig();
        excelconfig.FileName = "检验任务分配.xls";
        excelconfig.HeadFont = "微软雅黑";
        excelconfig.HeadPoint = 10;
        excelconfig.IsAllSizeColumn = true;
        excelconfig.ColumnModel = new List<ExcelColumnModel>();
        foreach (var item in input.selectKey.Split(',').ToList())
        {
            var isExist = paramList.Find(p => p.field == item);
            if (isExist != null)
                excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
        }

        var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
        ExcelExportHelper<QmsBaseMastercheckdistInfoOutput>.Export(exportData, excelconfig, addPath);
        var fileName = _userManager.UserId + "|" + addPath + "|xls";
        return new
        {
            name = excelconfig.FileName,
            url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "SHZY")
        };
    }

    /// <summary>
    /// 批量删除检验任务分配.
    /// </summary>
    /// <param name="ids">主键数组.</param>
    /// <returns></returns>
    [HttpPost("batchRemove")]
    public async Task BatchRemove([FromBody] List<string> ids)
    {
        var entitys = await _repository.Context.Queryable<QmsBaseMastercheckdistEntity>().In(it => it.Id, ids).ToListAsync();
        if (entitys.Count > 0)
        {
            try
            {
                // 开启事务
                _db.BeginTran();

                // 批量删除检验任务分配
                await _repository.Context.Deleteable<QmsBaseMastercheckdistEntity>().In(it => it.Id, ids).ExecuteCommandAsync();

                // 关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                // 回滚事务
                _db.RollbackTran();

                throw Oops.Oh(ErrorCode.COM1002);
            }
        }
    }

    /// <summary>
    /// 更新检验任务分配.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] QmsBaseMastercheckdistUpInput input)
    {
        if (await _repository
            .Where(w => w.EmployeeCode == input.employeeCode)
            .Where(w => w.SupplierNo == input.supplierNo)
            .Where(w => w.SupplierClassify == input.supplierClassify)
            .Where(w => w.MatnrCode == input.matnrCode)
            .Where(w => w.MatnrGroupCode == input.matnrGroupCode)
            .Where(w => w.DeleteMark == null)
            .Where(w => w.Id != input.id)
            .AnyAsync())
            throw Oops.Oh(ErrorCode.COM1004);

        var entity = input.Adapt<QmsBaseMastercheckdistEntity>();
        entity.LastModifyUserId = _userManager.UserId;
        entity.LastModifyTime = DateTime.Now;
        var isOk = await _repository.Context.Updateable(entity).UpdateColumns(it => new
        {
            it.MatnrCode,
            it.MatnrGroupCode,
            it.SupplierNo,
            it.SupplierClassify,
            it.EmployeeCode,
            it.LastModifyUserId,
            it.LastModifyTime,
            it.EnabledMark,
        }).CallEntityMethod(m => m.LastModify())
        .ExecuteCommandHasChangeAsync();

        if (!isOk) throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 删除检验任务分配.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        //var isOk = await _repository.Context.Deleteable<QmsBaseMastercheckdistEntity>().Where(it => it.Id.Equals(id)).ExecuteCommandAsync();
        //if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);

        var isOk = await _repository.Context.Updateable<QmsBaseMastercheckdistEntity>()
           .SetColumns(it => new QmsBaseMastercheckdistEntity()
           {
               DeleteTime = DateTime.Now,
               DeleteMark = 1,
               DeleteUserId = _userManager.UserId
           }).Where(x => x.Id == id)
           .ExecuteCommandHasChangeAsync();

        if (!isOk) throw Oops.Oh(ErrorCode.COM1002);
    }
}